home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / T U R B O Language / Turbo Pascal V7.0 / ONLINE.ZIP / UTILS.DOC < prev   
Text File  |  1992-10-30  |  47KB  |  1,288 lines

  1. =======================================================================
  2.                        Turbo Pascal Utilities
  3. =======================================================================
  4.  
  5. -----------------------------------------------------------------------
  6.                          Table of Contents
  7. -----------------------------------------------------------------------
  8.  1. The TOUCH utility
  9.  2. The GREP utility
  10.      The GREP switches
  11.      How to search using GREP
  12.      Examples using GREP
  13.  3. The BINOBJ utility
  14.  4. Using TPUMOVER, the unit mover
  15.      A review of unit files
  16.      Using TPUMOVER
  17.  5. The Stand-Alone MAKE Utility
  18.      Creating makefiles
  19.       Comments
  20.       Explicit rules
  21.       Implicit rules
  22.       Command lists
  23.       Macros
  24.        Defined test macro ($d)
  25.        Base file name macro ($*)
  26.        Full file name macro ($<)
  27.        File name path macro ($:)
  28.        File name and extension macro ($.)
  29.        File name only macro ($&)
  30.       Directives
  31.      Using MAKE
  32.       The BUILTINS.MAK file
  33.       How MAKE searches for files
  34.       MAKE command-line options
  35.       MAKE error messages
  36.        Fatal errors
  37.        Errors
  38. -----------------------------------------------------------------------
  39.  
  40. This file describes three stand-alone utility programs that come
  41. with Turbo Pascal: TOUCH, GREP, BINOBJ, TPUMOVER and MAKE.
  42.  
  43. ======================
  44.  1. The TOUCH Utility
  45. ======================
  46.  
  47. There are times when you want to force a particular target file
  48. to be recompiled or rebuilt, even though no changes have been
  49. made to its sources. One way to do this is to use the TOUCH
  50. utility included with Turbo Pascal. TOUCH changes the date and
  51. time of one or more files to the current date and time, making it
  52. "newer" than the files that depend on it.
  53.  
  54. To force a target file to be rebuilt, "touch" one of the files
  55. that target depends on. To touch a file (or files), enter
  56.  
  57.    touch filename [ filename ... ]
  58.  
  59. at the DOS prompt. TOUCH will then update the file's creation
  60. date(s).
  61.  
  62. Once you do this, you can invoke MAKE to rebuild the touched
  63. target file(s).
  64.  
  65.  
  66. =====================
  67.  2. The GREP Utility
  68. =====================
  69.  
  70. GREP is a powerful search utility that can look for text in
  71. several files at once.
  72.  
  73. The command-line syntax for GREP follows:
  74.  
  75.    GREP [options] searchstring [filespec ... ]
  76.  
  77. where options consists of one or more single characters preceded
  78. by a hyphen, searchstring defines the pattern to search for, and
  79. filespec is the file specification. filespec tells GREP which
  80. files (or groups of files) to search; it can be an explicit file
  81. name or a generic file name incorporating the DOS wildcards (?
  82. and *). You can also enter a path as part of filespec; if you use
  83. filespec without a path, GREP only searches the current
  84. directory. If you don't specify filespec, input to GREP must be
  85. specified by redirecting stdin or piping.
  86.  
  87.  
  88.  The GREP Switches
  89. ===================
  90.  
  91. In the command line, options are one or more single characters
  92. preceded by a hyphen (-). Each individual character is a switch
  93. that you can turn on or off: type the plus symbol (+) after a
  94. character to turn the option on, or type a hyphen (-) after the
  95. character to turn the option off.
  96.  
  97. The default is on (the + is implied): for example, -R means the
  98. same thing as -R+. You can list multiple options individually
  99. like this: -I -D -L). Or you can combine them like this: -ILD or
  100. -IL -D, and so on). It's all the same to GREP.
  101.  
  102. Here is a list of the switches and their meanings:
  103.  
  104.    -C   Count only: Only a count of matching lines is printed.
  105.         For each file that contains at least one matching line,
  106.         GREP prints the file name and a count of the number of
  107.         matching lines. Matching lines are not printed.
  108.  
  109.    -D   Directories: For each filespec specified on the command
  110.         line, GREP searches for all files that match the file
  111.         specification, both in the directory specified and in all
  112.         subdirectories below the specified directory. If you give
  113.         a filespec without a path, GREP assumes the files are in
  114.         the current directory.
  115.  
  116.    -I   Ignore case: GREP ignores upper/lowercase differences
  117.         (case folding). GREP treats all letters a-z as being
  118.         identical to the corresponding letters A-Z in all
  119.         situations.
  120.  
  121.    -L   List match files: Only the name of each file containing a
  122.         match is printed. After GREP finds a match, it prints the
  123.         file name and processing immediately moves on to the next
  124.         file.
  125.  
  126.    -N   Numbers: Each matching line that GREP prints is preceded
  127.         by its line number.
  128.  
  129.    -O   UNIX output format: Changes the output format of matching
  130.         lines to support more easily the UNIX style of
  131.         command-line piping. All lines of output are preceded by
  132.         the name of the file which contained the matching line.
  133.  
  134.    -R   Regular expression search: The text defined by
  135.         searchstring is treated as a regular expression instead
  136.         of as a literal string.
  137.  
  138.    -U   Update options: GREP will combine the options given on
  139.         the command line with its default options and write these
  140.         to the GREP.COM file as the new defaults. (In other
  141.         words, GREP is self-configuring.) This option allows you
  142.         to tailor the default option settings to your own taste.
  143.  
  144.    -V   Non-match: Only non-matching lines are printed. Only
  145.         lines that do not contain the search string are
  146.         considered to be non-matching lines.
  147.  
  148.    -W   Word search: Text found which matches the regular
  149.         expression will be considered a match only if the
  150.         character immediately preceding and following cannot be
  151.         part of a word. The default word character set includes
  152.         A-Z, 9-0, and the underbar (_). An alternate form of this
  153.         option allows you to specify the set of legal word
  154.         characters. Its form is -W[set], where set is any valid
  155.         regular expression set definition. If alphabetic
  156.         characters are used to define the set, the set will
  157.         automatically be defined to contain both the upper and
  158.         lower case values for each letter in the set, regardless
  159.         of how it is typed, even if the search is case-sensitive.
  160.         If the -W option is used in combination with the -U
  161.         option, the new set of legal characters is saved as the
  162.         default set.
  163.  
  164.    -Z   Verbose: GREP prints the file name of every file
  165.         searched. Each matching line is preceded by its line
  166.         number. A count of matching lines in each file is given,
  167.         even if the count is zero.
  168.  
  169. Several of these options are in direct conflict with each other.
  170. In these cases, the following order applies (the first one is the
  171. one that takes precedence):
  172.  
  173.    -Z   -L   -C   -N
  174.  
  175. Each occurrence of an option overrides the previous definition:
  176. Its state reflects the way you last set it. At any given time,
  177. each option can only be on or off.
  178.  
  179. You can install your preferred default setting for each option in
  180. GREP.COM with the -U option. For example, if you want GREP to
  181. always do a verbose search (-Z on), you can install it with the
  182. following command:
  183.  
  184.    GREP -U -Z
  185.  
  186.  
  187.  How to Search Using GREP
  188. ==========================
  189.  
  190. The value of searchstring defines the pattern GREP will search
  191. for.  A search string can be either a (via the -R switch) or a
  192. literal string. In regular expressions, operators govern the
  193. search; literal strings have no operators.
  194.  
  195. You can enclose the search string in quotation marks to prevent
  196. spaces and tabs from being treated as delimiters. Matches will
  197. not cross line boundaries (a match must be contained in a single
  198. line).
  199.  
  200. When the -R switch is used, the search string is treated as a
  201. regular expression (as opposed to a literal expression), and the
  202. following symbols take on special meanings:
  203.  
  204.    ^   A caret at the start of the expression matches the start
  205.        of a line.
  206.  
  207.    $   A dollar sign at the end of the expression matches the end
  208.        of a line.
  209.  
  210.    .   A period matches any character.
  211.  
  212.    *   An expression followed by an asterisk wildcard matches
  213.        zero or more occurrences of that expression: fo* matches
  214.        f, fo, foo, etc.
  215.  
  216.    +   An expression followed by a plus sign matches one or more
  217.        occurrences of that expression: fo+ matches fo, foo, etc.,
  218.        but not f.
  219.  
  220.    []  A string enclosed in brackets matches any character in
  221.        that string, but no others. If the first character in the
  222.        string is a caret (^), the expression matches any
  223.        character except the characters in the string. For
  224.        example, [xyz] matches x, y, and z, while [^xyz] matches a
  225.        and b, but not x or y. A range of characters can be
  226.        specified by two characters separated by a hyphen (-).
  227.        These can be combined to form expressions like [?a-bd-z]
  228.        to match ? and any letter except c.
  229.  
  230.    \   The backslash "escape character" tells GREP to search for
  231.        the literal character that follows it. For example, \.
  232.        matches a period instead of any character.
  233.  
  234.    Note: Four characters (?, +, *, and .) do not have any special
  235.    meaning when used in a set. The character ^ is only treated
  236.    specially if it immediately follows the beginning of the set
  237.    (that is, immediately after the [).
  238.  
  239. Any ordinary character not mentioned in this list matches that
  240. character. A concatenation of regular expressions is a regular
  241. expression.
  242.  
  243.  
  244.  Examples Using GREP
  245. =====================
  246.  
  247. The following examples assume all options default to off.
  248.  
  249. ----------------------------------------------------------------
  250.  
  251. Search String   grep -n function dirdemo.pas
  252.  
  253. Finds       File DIRDEMO.PAS:
  254.             51        LessFunc = function(X, Y: DirPtr): Boolean;
  255.             60      function NumStr(N, D: Integer): String;
  256.             73      function LessName(X, Y: DirPtr): Boolean;
  257.             78      function LessSize(X, Y: DirPtr): Boolean;
  258.             83      function LessTime(X, Y: DirPtr): Boolean;
  259.  
  260. Remarks     Finds all functions in the file DIRDEMO.PAS. The -N
  261.             tells GREP to precede each matched line with its line
  262.             number.
  263.  
  264. -----------------------------------------------------------------
  265.  
  266. Search String   grep {\$ dirdemo.pas
  267.  
  268. Finds       File DIRDEMO.PAS:
  269.             {$I-,S-}
  270.             {$M 8192,8192,655360}
  271.             {$F+}
  272.             {$F-}
  273.  
  274. Remarks     Finds all compiler directives in DIRDEMO.PAS. The \
  275.             (backslash) preceding the $ is necessary. Without it,
  276.             the $ would indicate the end of the line. All lines
  277.             with { (curly bracket) as the last character would
  278.             match this pattern and be printed out.
  279.  
  280. -----------------------------------------------------------------
  281.  
  282. Search String   grep -i "^ *function.*).*real" *.pas
  283.  
  284. Finds       File WORKERS.PAS:
  285.             function RoundPay(Wages: Real): Real;
  286.  
  287. Remarks     Finds all lines that begin with zero or more spaces
  288.             followed by the word function, followed by any string
  289.             of zero or more characters, followed by a
  290.             parenthesis, followed by another string of zero or
  291.             more characters, followed by the word Real, and
  292.             ignores case. The net effect is to search for all
  293.             functions returning a Real. See if you can think of
  294.             other ways to do this.
  295.  
  296.             The double quotes are necessary because of the space
  297.             in the pattern string. The quotes tell the DOS
  298.             command-line processor to treat the intervening
  299.             characters as a single argument. Without the quotes,
  300.             DOS will think the search string is actually two
  301.             arguments, and GREP will think that everything after
  302.             ^ (the caret character) refers to file names, and
  303.             will complain
  304.  
  305.             No files matching: *FUNCTION.*).*.
  306.  
  307.  
  308. =======================
  309.  3. The BINOBJ Utility
  310. =======================
  311.  
  312. A utility program called BINOBJ.EXE has been added to convert any
  313. file to an .OBJ file so it can be linked into a pascal program as
  314. a "procedure." This is useful if you have a binary data file that
  315. must reside in the code segment or is too large to make into a
  316. typed constant array. For example, you can use BINOBJ with the
  317. Graph unit to link the graphics driver or font files directly
  318. into your .EXE file. Then, to use your graph program, you need
  319. only have the .EXE file (see the example BGILINK.PAS).
  320.  
  321. BINOBJ takes three parameters:
  322.  
  323.    BINOBJ  <source[.BIN]>  <destination[.OBJ]>  <public name>
  324.  
  325. where source is the binary file to convert, destination is the
  326. name of the .OBJ to be produced, and public name is the name of
  327. the procedure as it will be declared in your pascal program.
  328.  
  329. The following example, the procedure ShowScreen, takes a pointer
  330. as a parameter and moves 4000 bytes of data to screen memory. The
  331. file called MENU.DTA contains the image of the main menu screen
  332. (80 * 25 * 2 = 4000 bytes).
  333.  
  334. Here's a simple (no error-checking) version of MYPROG.PAS:
  335.  
  336.    program MyProg;
  337.  
  338.    uses Crt;
  339.  
  340.    procedure ShowScreen(ScreenData : Pointer);
  341.    { Display a screenful of data--no error-checking! }
  342.    var
  343.      ScreenSegment: Word;
  344.  
  345.    begin
  346.      if (Lo(LastMode) = 7) then      { Mono? }
  347.        ScreenSegment := $B000
  348.      else
  349.        ScreenSegment := $B800;
  350.      Move(ScreenData^,               { From pointer }
  351.       Ptr(ScreenSegment, 0)^,        { To video memory }
  352.       4000);                         { 80 * 25 * 2 }
  353.    end;
  354.  
  355.    var
  356.      MenuP : Pointer;
  357.      MenuF : file;
  358.    begin
  359.      Assign(MenuF, 'MENU.DTA');      { Open screen data file }
  360.      Reset(MenuF, 1);
  361.      GetMem(MenuP, 4000);            { Allocate buffer on heap }
  362.      BlockRead(MenuF, MenuP^, 4000); { Read screen data }
  363.      Close(MenuF);
  364.      ShowScreen(MenuP);              { Display screen }
  365.    end.
  366.  
  367.  
  368. The screen data file (MENU.DTA) is opened and then read into a
  369. buffer on the heap. Both MYPROG.EXE and MENU.DTA must be present
  370. at run-time for this program to work. You can use BINOBJ to
  371. convert MENU.DTA to an .OBJ file (MENUDTA.OBJ) and tell it to
  372. associate the data with a procedure called MenuData. Then you can
  373. declare the fake external procedure MenuData, which actually
  374. contains the screen data. Once you link in the .OBJ file with the
  375. $L compiler directive, MenuData will be 4000 bytes long and
  376. contain your screen data. First, run BINOBJ on MENU.DTA:
  377.  
  378.    binobj MENU.DTA MENUDTA MenuData
  379.  
  380. The first parameter, MENU.DTA, shows a familiar file of screen
  381. data; the second, MENUDTA, is the name of the .OBJ file to be
  382. created (since you didn't specify an extension, .OBJ will be
  383. added). The last parameter, MenuData, is the name of the external
  384. procedure as it will be declared in your program. Now that you've
  385. converted MENU.DTA to an .OBJ file, here's what the new
  386. MYPROG.PAS looks like:
  387.  
  388.    program MyProg;
  389.  
  390.    uses Crt;
  391.  
  392.    procedure ShowScreen(ScreenData : Pointer);
  393.    { Display a screenful of data--no error checking! }
  394.    var
  395.      ScreenSegment: Word;
  396.    begin
  397.      if (Lo(LastMode) = 7) then             { Mono? }
  398.        ScreenSegment := $B000
  399.      else
  400.        ScreenSegment := $B800;
  401.      Move(ScreenData^,                      { From pointer }
  402.       Ptr(ScreenSegment, 0)^,               { To video memory }
  403.       4000);                                { 80 * 25 * 2 }
  404.    end;
  405.  
  406.    procedure MenuData; external;
  407.    {$L MENUDTA.OBJ }
  408.    begin
  409.      ShowScreen(@MenuData);                 { Display screen }
  410.    end.
  411.  
  412. Notice that ShowScreen didn't change at all, and that the ADDRESS
  413. of your procedure is passed using the @ operator.
  414.  
  415. ===================================
  416.  4. Using TPUMOVER, the Unit Mover
  417. ===================================
  418.  
  419. When you write units, you want to make them easily available to any
  420. programs that you develop. We'll now show you how to use TPUMOVER to
  421. remove seldom-used units from TURBO.TPL, and how to insert often-used
  422. units into TURBO.TPL.
  423.  
  424.  
  425.  A Review of Unit Files
  426. ========================
  427.  
  428. There are two types of unit files: .TPU files and .TPL files. When you
  429. compile a unit, Turbo Pascal puts the resulting object code in a .TPU
  430. (Turbo Pascal Unit) file, which always contains exactly one unit.
  431.  
  432. A .TPL (Turbo Pascal Library) file, on the other hand, can contain multiple
  433. units. For example, several units that come on your Turbo Pascal disks
  434. are in the file TURBO.TPL. The file TURBO.TPL is currently the only
  435. library file Turbo Pascal will load units from.
  436.  
  437. You may have noticed, though, that you can use the standard Turbo Pascal
  438. units without giving a file name. That's because these units are stored in
  439. the Turbo Pascal standard unit file--TURBO.TPL on your distribution disk.
  440. Because the units are in that file, any program can use them without
  441. "knowing" their location.
  442.  
  443. Suppose you have a unit called TOOLS.TPU, and you use it in many different
  444. programs. Though adding Tools to TURBO.TPL takes up memory (TURBO.TPL is
  445. automatically loaded into memory by the compiler), adding it to the
  446. resident library makes "using" Tools faster because the unit is in memory
  447. instead of on disk.
  448.  
  449. There are five standard units already in TURBO.TPL: System, Overlay,
  450. Printer, Crt, and Dos.
  451.  
  452.  
  453.  Using TPUMOVER
  454. ================
  455.  
  456. You can use several command-line parameters that let you manipulate units
  457. quickly. The syntax for these parameters is
  458.  
  459.    TPUMOVER filename operations
  460.  
  461. where filename is either a .TPU file or a .TPL file,
  462.       and operations is an optional list of one or more of the following
  463.       commands:
  464.  
  465.          +unitname    Add a unit to the library.
  466.          -unitname    Delete a unit from the library.
  467.          *unitname    Extract a unit from the library.
  468.  
  469. If no operations are specified, TPUMOVER lists the units in the library
  470. file along with size and dependency information.
  471.  
  472.  
  473. =================================
  474.  5. The Stand-Alone MAKE Utility
  475. =================================
  476.  
  477. This section contains complete documentation for creating makefiles and
  478. using MAKE.
  479.  
  480.  
  481.  Creating Makefiles
  482. ====================
  483.  
  484. A makefile contains the definitions and relationships needed to help MAKE
  485. keep your program(s) up to date. You can create as many makefiles as you
  486. want and name them whatever you want. If you don't specify a makefile when
  487. you run MAKE (using the -f option), then MAKE looks for a file with the
  488. default name MAKEFILE.
  489.  
  490. You create a makefile with any ASCII text editor, such as Turbo Pascal's
  491. built-in interactive editor. All rules, definitions, and directives end
  492. with a carriage return; if a line is too long, you can continue it to the
  493. next line by placing a backslash (\) as the last character on the line.
  494.  
  495. Whitespace--spaces and tabs--is used to separate adjacent identifiers (such
  496. as dependencies) and to indent commands within a rule.
  497.  
  498. Creating a makefile is almost like writing a program--with definitions,
  499. commands, and directives. 
  500.  
  501.  Comments
  502. ----------
  503.  
  504. Comments begin with a number sign (#); the rest of the line following the #
  505. is ignored by MAKE. Comments can be placed anywhere and never have to start
  506. in a particular column.
  507.  
  508.  
  509.  Explicit Rules
  510. ----------------
  511.  
  512. Explicit rules take the form
  513.  
  514.    target [target ... ]: [source source ... ]
  515.       [command]
  516.       [command]
  517.       ...
  518.  
  519. where target is the file to be updated, source is a file upon which target
  520. depends, and command is any valid MS-DOS command (including invocation of
  521. .BAT files and execution of .COM and .EXE files).
  522.  
  523. Explicit rules define one or more target names, zero or more source files,
  524. and an optional list of commands to be performed. Target and source file
  525. names listed in explicit rules can contain normal MS-DOS drive and
  526. directory specifications, but they cannot contain wildcards.
  527.  
  528. Syntax here is important. target must be at the start of a line (in column
  529. 1), and each command must be indented (preceded by at least one space
  530. character or tab). As mentioned before, the backslash (\) can be used as a
  531. continuation character if the list of source files or a given command is
  532. too long for one line. Finally, both the source files and the commands are
  533. optional; it is possible to have an explicit rule consisting only of
  534.  
  535.    target [target ...] followed by a colon.
  536.  
  537. The idea behind an explicit rule is that the command or commands listed
  538. will create or update target, usually using the source files. When MAKE
  539. encounters an explicit rule, it first checks to see if any of the source
  540. files are target files elsewhere in the makefile. If so, those rules are
  541. evaluated first.
  542.  
  543. Once all the source files have been created or updated based on other
  544. explicit (or implicit) rules, MAKE checks to see if target exists. If not,
  545. each command is invoked in the order given. If target does exist, its time
  546. and date of last modification are compared against the time and date for
  547. each source. If any source has been modified more recently than target, the
  548. list of commands is executed.
  549.  
  550. A given file name can occur on the left side of an explicit rule only once
  551. in a given execution of MAKE.
  552.  
  553. Each command line in an explicit rule begins with whitespace. MAKE
  554. considers all lines following an explicit rule to be part of the command
  555. list for that rule, up to the next line that begins in column 1 (without
  556. any preceding whitespace) or up to the end of the file. Blank lines are
  557. ignored.
  558.  
  559. An explicit rule, with no command lines following it, is treated a little
  560. differently than an explicit rule with command lines.
  561.  
  562.    o If an explicit rule exists for a target with commands, the only files
  563.      that the target depends on are the ones listed in the explicit rule.
  564.  
  565.    o If an explicit rule has no commands, the targets depend on the files
  566.      given in the explicit rule, and they also depend on any file that
  567.      matches an implicit rule for the target(s).
  568.  
  569. Here are some examples of explicit rules from a makefile:
  570.  
  571.    myutil.obj: myutil.asm
  572.      tasm myutil.asm,myutil.obj;
  573.  
  574.    myapp.exe:  myapp.pas myglobal.tpu myutils.tpu
  575.      tpc myapp /Tc:\tp5\bin
  576.  
  577.    o The first explicit rule states that MYUTIL.OBJ depends upon
  578.      MYUTIL.ASM, and that MYUTIL.OBJ is created by executing the given
  579.      TASM command.
  580.  
  581.    o The second rule states that MYAPP.EXE depends upon MYAPP.PAS,
  582.      MYGLOBAL.TPU, and MYUTILS.TPU, and is created by the given TPC
  583.      command. (The /T plus path name in these examples will be explained
  584.      later.)
  585.  
  586. If you reorder the rules so that the one for MYAPP.EXE comes first,
  587. followed by the others, MAKE will recompile (or reassemble) only the files
  588. that it has to in order to update everything correctly. This is because a
  589. MAKE with no target on the command line will try to execute the first
  590. explicit rule it finds in the makefile.
  591.  
  592.  
  593.  Implicit Rules
  594. ----------------
  595.  
  596. MAKE also allows you to define implicit rules, which are generalizations of
  597. explicit rules. Here's an example to illustrate the relationship between
  598. the two types. Consider this explicit rule from the previous sample
  599. program:
  600.  
  601.    myutil.obj: myutil.asm
  602.      tasm myutil.asm,myutil.obj;
  603.  
  604. This rule is a common one, because it follows a general principle: An .OBJ
  605. file is dependent on the .ASM file with the same file name and is created
  606. by executing TASM (Turbo Assember). In fact, you might have a makefile
  607. where you have several (or even several dozen) explicit rules following
  608. this same format.
  609.  
  610. By redefining the explicit rule as an implicit rule, you can eliminate all
  611. the explicit rules of the same form. As an implicit rule, it would look
  612. like this:
  613.  
  614.    .asm.obj:
  615.      tasm $*.asm,$*.obj;
  616.  
  617. This rule means, "any file ending with .OBJ depends on the file with the
  618. same name that ends in .ASM, and the .OBJ file is created using the command
  619.  
  620.    tasm $*.asm,$*.obj
  621.  
  622. where $* represents the file's name with no extension." (The symbol $* is a
  623. special macro and is discussed in the next section.)
  624.  
  625. The syntax for an implicit rule follows:
  626.  
  627.    .source_extension.target_extension:
  628.      {command}
  629.      {command}
  630.      ...
  631.  
  632. Note the commands are optional and must be indented. The source_extension
  633. (which must begin in column 1) is the extension of the source file, that
  634. is, it applies to any file having the format
  635.  
  636.    fname.source_extension
  637.  
  638. Likewise, the target_extension refers to the the file
  639.  
  640.    fname.target_extension
  641.  
  642. where fname is the same for both files. In other words, this implicit rule
  643. replaces all explicit rules having the format
  644.  
  645.    fname.target_extension:fname.source_extension
  646.      [command]
  647.      [command]
  648.      ...
  649.  
  650. for any fname.
  651.  
  652. Implicit rules are used if no explicit rule for a given target can be found
  653. or if an explicit rule with no commands exists for the target.
  654.  
  655. The extension of the file name in question is used to determine which
  656. implicit rule to use. The implicit rule is applied if a file is found with
  657. the same name as the target, but with the mentioned source extension. For
  658. example, suppose you had a makefile (named MAKEFILE) whose contents were
  659.  
  660.    .asm.obj:
  661.      tasm $*.asm,$*.obj;
  662.  
  663. If you had an assembly language routine named RATIO.ASM that you wanted to
  664. compile to RATIO.OBJ, you could use the command
  665.  
  666.    make ratio.obj
  667.  
  668. MAKE would take RATIO.OBJ to be the target and create it by executing the
  669. command:
  670.  
  671.    tasm ratio.asm,ratio.obj;
  672.  
  673. Implicit rules are also used if an explicit rule is given with no commands.
  674. Suppose, as mentioned before, you had the following implicit rule at the
  675. start of your makefile:
  676.  
  677.    .pas.tpu:
  678.      tpc $<
  679.  
  680. You could then rewrite some explicit rules as follows:
  681.  
  682.    myglobal.tpu: myglobal.pas
  683.    myutils.tpu: myutils.pas myglobal.tpu myutil.obj
  684.  
  685. Since you don't have explicit information on how to create these .TPU
  686. files, MAKE applies the implicit rule defined earlier.
  687.  
  688. Several implicit rules can be written with the same target extension, but
  689. only one such rule can apply at a time. If more than one implicit rule
  690. exists for a given target extension, each rule is checked in the order the
  691. rules appear in the makefile, until all applicable rules are checked.
  692.  
  693. MAKE uses the first implicit rule that it discovers for a file with the
  694. source extension. Even if the commands of that rule fail, no more implicit
  695. rules are checked.
  696.  
  697. All lines following an implicit rule are considered to be part of the
  698. command list for the rule, up to the next line that begins without
  699. whitespace or to the end of the file. Blank lines are ignored. The syntax
  700. for a command line is provided later in this appendix.
  701.  
  702. MAKE does not know the full file name with an implicit rule, as it does
  703. with explicit rules. For that reason, special macros are provided with MAKE
  704. that allow you to include the name of the file being built by the rule.
  705.  
  706.  
  707.  Command Lists
  708. ---------------
  709.  
  710. Commands in a command list must be indented--that is, preceded by at least
  711. one space character or tab--and take the form
  712.  
  713.    [ prefix ... ] command_body
  714.  
  715. Each command line in a command list consists of an (optional) list of
  716. prefixes, followed by a single command body.
  717.  
  718. The prefixes allowed in a command modify the treatment of these commands by
  719. MAKE. The prefix is either the at (@) sign or a hyphen (-) followed
  720. immediately by a number.
  721.  
  722.    @   Keeps MAKE from displaying the command before executing it. The
  723.        display is hidden even if the -s option was not given on the MAKE
  724.        command line. This prefix applies only to the command on which it
  725.        appears.
  726.  
  727.    -num   Affects how MAKE treats exit codes. If a number (num) is
  728.           provided, then MAKE will abort processing only if the exit status
  729.           exceeds the number given. In this example, MAKE will abort only
  730.           if the exit status exceeds 4:
  731.  
  732.              -4 myprog sample.x
  733.  
  734.           If no -num prefix is given, MAKE checks the exit status for the
  735.           command. If the status is nonzero, MAKE will stop and delete the
  736.           current target file.
  737.  
  738.    -   With a hyphen but no number, MAKE will not check the exit status at
  739.        all. Regardless of what the exit status was, MAKE will continue.
  740.  
  741. The command body is treated exactly as if it were entered as a line to
  742. COMMAND.COM, with the exception that redirection and pipes are not
  743. supported. MAKE executes the following built-in commands by invoking a copy
  744. of COMMAND.COM to perform them:
  745.  
  746.    BREAK      CD      CHDIR      CLS      COPY
  747.    MD         MKDIR   PATH       PROMPT   REN
  748.    RENAME     SET     TIME       TYPE     VER
  749.    VERIFY     VOL
  750.  
  751. MAKE searches for any other command name using the MS-DOS search algorithm:
  752.  
  753.    o The current directory is searched first, followed by each directory
  754.      in the path.
  755.  
  756.    o In each directory, first a file with the extension .COM is checked,
  757.      then an .EXE file, and finally a .BAT.
  758.  
  759.    o If a .BAT file is found, a copy of COMMAND.COM is invoked to execute
  760.      the batch file.
  761.  
  762.  
  763. This command will cause MYPROG.PAS to be searched for, using the full
  764. search algorithm:
  765.  
  766.    tpc myprog.pas /$B+,R+,I+
  767.  
  768.  
  769.  Macros
  770. --------
  771.  
  772. Often certain commands, file names, or options are used again and again in
  773. your makefile. In an example earlier in this appendix, all the TPC commands
  774. used the switch /Tc:\tp5\bin, which means that the files TPC.CFG and
  775. TURBO.TPL are in the subdirectory C:\TP5\BIN. Suppose you wanted to switch
  776. to another subdirectory for those files; what would you do? You could go
  777. through and modify all the /T options, inserting the appropriate path name.
  778. Or, you could define a macro.
  779.  
  780. A macro is a name that represents some string of characters (letters and
  781. digits). A macro definition gives a macro name and the expansion text;
  782. thereafter, when MAKE encounters the macro name, it replaces the name with
  783. the expansion text.
  784.  
  785. Suppose you defined the following macro at the start of your makefile:
  786.  
  787.    TURBO=c:\tp5\bin
  788.  
  789. You've defined the macro TURBO, which is equivalent to the string
  790. c:\tp5\bin. You could now rewrite the makefile as follows:
  791.  
  792.    TURBO=c:\tp5\bin
  793.    myapp.exe:  myapp.pas myglobal.tpu myutils.tpu
  794.      tpc myapp /T$(TURBO)
  795.  
  796.    myutils.tpu: myutils.pas myglobal.tpu myutil.obj
  797.      tpc myutils /T$(TURBO)
  798.  
  799.  
  800. Everywhere the Turbo directory is specified, you use the macro invocation
  801. $(TURBO). When you run MAKE, $(TURBO) is replaced with its expansion text,
  802. c:\TP5.BIN. The result is the same set of commands you had before but with
  803. greater flexibility.
  804.  
  805. In fact, if you leave out the first line altogether, you can specify which 
  806. subdirectory you want each time you run MAKE, using the -D (Define) option:
  807.  
  808.    make -DTURBO=c:\tp5\project
  809.  
  810. Macro definitions take the form
  811.  
  812.    macro_name=expansion text
  813.  
  814. where macro_name is the name of a macro made up of a string of letters and
  815. digits with no whitespace in it, though you can have whitespace between
  816. macro_name and the equal sign (=). [expansion text] is any arbitrary string
  817. containing letters, digits, whitespace, and punctuation; it is ended by a
  818. carriage return.  Note that macros are case sensitive.  Thus the macro
  819. names Turbo, turbo and TURBO are all different.
  820.  
  821. If macro_name has previously been defined, either by a macro definition in
  822. the makefile or by the -D option on the MAKE command line, the new
  823. definition replaces the old.
  824.  
  825. Macros are invoked in your makefile with the format
  826.  
  827.    $(macro_name)
  828.  
  829. Macros in macros: Macros cannot be invoked on the left (macro_name) side of
  830. a macro definition. They can be used on the right (expansion text) side,
  831. but they are not expanded until the macro being defined is invoked. In
  832. other words, when a macro invocation is expanded, any macros embedded in
  833. its expansion text are also expanded.
  834.  
  835. MAKE comes with several special predefined macros built-in: $d, $*, $<, $:,
  836. $., and $&. The first is a defined test macro, used in the conditional
  837. directives !if and !elif; the others are file name macros, used in explicit
  838. and implicit rules. The various file name macros work in similar ways,
  839. expanding to some variation of the full path name of the file being built.
  840. In addition, the current SET environment strings are automatically loaded
  841. as macros, and the macro __MAKE__ is defined to be 1 (one).
  842.  
  843.  
  844.  Defined Test Macro ($d)
  845.  
  846. This macro expands to 1 if the given macro name is defined, or to 0 if it
  847. is not. The content of the macro's expansion text does not matter. This
  848. special macro is allowed only in !if and !elif directives. For example, if
  849. you wanted to modify your makefile so that it would use a particular Turbo
  850. Pascal directory if you didn't specify one, you could put this at the start
  851. of your makefile:
  852.  
  853.    !if !$d(TURBO)            # if TURBO is not defined
  854.    TURBO=c:\tp5\bin          # define it to C:\TP5\BIN
  855.    !endif
  856.  
  857. If you invoke MAKE with the command line
  858.  
  859.    make -DTURBO=c:\tp5\project
  860.  
  861. then TURBO is defined as c:\tp5\project. If, however, you just invoke MAKE
  862. by itself,
  863.  
  864.    make
  865.  
  866. then TURBO is defined as c:\tp5\bin, your "default" subdirectory.
  867.  
  868.  
  869.  Base File Name Macro ($*)
  870.  
  871. This macro is allowed in the commands for an explicit or an implicit rule.
  872. The macro expands to the file name being built, excluding any extension,
  873. like this:
  874.  
  875.    File name is A:\P\TESTFILE.PAS
  876.    $* expands to A:\P\TESTFILE
  877.  
  878. For example, you could modify the explicit MYAPP.EXE rule already given to
  879. look like this:
  880.  
  881.    myapp.exe:  myapp.pas myglobal.tpu myutils.tpu
  882.      tpc $* /T$(TURBO)
  883.  
  884.  
  885.  Full File Name Macro ($<)
  886.  
  887. The full file name macro ($<) is also used in the commands for an explicit
  888. or implicit rule. In an explicit rule, $< expands to the full target file
  889. name (including extension), like this:
  890.  
  891.    File name is A:\P\TESTFILE.PAS
  892.    $< expands to A:\P\TESTFILE.PAS
  893.  
  894. In an implicit rule, $< takes on the file name plus the source extension.
  895. For example, the previous implicit rule
  896.  
  897.    .asm.obj:
  898.      tasm $*.asm,$*.obj;
  899.  
  900. can be rewritten as
  901.  
  902.    .asm.obj:
  903.       tasm $<,$*.obj;
  904.  
  905.  
  906.  File Name Path Macro ($:)
  907.  
  908. This macro expands to the path name (without the file name), like this:
  909.  
  910.    File name is A:\P\TESTFILE.PAS
  911.    $: expands to A:\P\
  912.  
  913.  
  914.  File Name and Extension Macro ($.)
  915.  
  916. This macro expands to the file name, with extension, like this:
  917.  
  918.    File name is A:\P\TESTFILE.PAS
  919.    $. expands to TESTFILE.PAS
  920.  
  921.  
  922.  File Name Only Macro ($&)
  923.  
  924. This macro expands to the file name only, without path or extension, like
  925. this:
  926.  
  927.    File name is A:\P\TESTFILE.PAS
  928.    $& expands to TESTFILE
  929.  
  930.  
  931.  Directives
  932. ------------
  933.  
  934. The version of MAKE bundled with Turbo Pascal allows something that other
  935. versions of MAKE don't: conditional directives similiar to those allowed
  936. for Turbo Pascal. You can use these directives to include other makefiles,
  937. to make the rules and commands conditional, to print out error messages,
  938. and to "undefine" macros.
  939.  
  940. Directives in a makefile begin with an exclamation point (!). Here is the
  941. complete list of MAKE directives:
  942.  
  943.    !include
  944.    !if
  945.    !else
  946.    !elif
  947.    !endif
  948.    !error
  949.    !undef
  950.  
  951. A file-inclusion directive (!include) specifies a file to be included into
  952. the makefile for interpretation at the point of the directive. It takes the
  953. following form:
  954.  
  955.    !include "filename"
  956.  
  957. or
  958.  
  959.    !include <filename>
  960.  
  961. These directives can be nested arbitrarily deep. If an include directive
  962. attempts to include a file that has already been included in some outer
  963. level of nesting (so that a nesting loop is about to start), the inner
  964. include directive is rejected as an error.
  965.  
  966. Conditional directives (!if, !elif, !else, and !endif) give a programmer a
  967. measure of flexibility in constructing makefiles. Rules and macros can be
  968. "conditionalized" so that a command-line macro definition (using the -D
  969. option) can enable or disable sections of the makefile.
  970.  
  971. The format of these directives parallels, but is more extensive than, the
  972. conditional directives allowed by Turbo Pascal:
  973.  
  974.    !if expression
  975.      [ lines ]
  976.    !endif
  977.  
  978.    !if expression
  979.      [ lines ]
  980.    !else
  981.      [ lines ]
  982.    !endif
  983.  
  984.    !if expression
  985.      [ lines ]
  986.    !elif expression
  987.      [ lines ]
  988.    !endif
  989.  
  990. The conditional directives form a group, with at least an !if directive
  991. beginning the group and an !endif directive closing the group.
  992.  
  993. The expression allowed in an !if or an !elif directive uses a syntax
  994. similar to that found in the C programming language. The expression is
  995. evaluated as a simple 32-bit signed integer expression.
  996.  
  997. Numbers can be entered as decimal, octal, or hexadecimal constants. For
  998. example, these are legal constants in an expression:
  999.  
  1000.    4536       # decimal constant
  1001.    0677       # octal constant (note the leading zero)
  1002.    0x23aF     # hexadecimal constant
  1003.  
  1004. and any of the following unary operators:
  1005.  
  1006.    -     negation
  1007.    ~     bit complement
  1008.    !     logical not
  1009.  
  1010. An expression can use any of the following binary operators:
  1011.  
  1012.    +     addition
  1013.    -     subtraction
  1014.    *     multiplication
  1015.    /     division
  1016.    %     remainder
  1017.    >>    right shift
  1018.    <<    left shift
  1019.    &     bitwise and
  1020.    |     bitwise or
  1021.    ^     bitwise exclusive or
  1022.    &&    logical and
  1023.    ||    logical or
  1024.    >     greater than
  1025.    <     less than
  1026.    >=    greater than or equal to
  1027.    <=    less than or equal to
  1028.    ==    equality
  1029.    !=    inequality
  1030.  
  1031. An expression can contain the following ternary operator:
  1032.  
  1033.    ? :   The operand before the ? is treated as a test.
  1034.  
  1035.          If the value of that operand is nonzero, then the second
  1036.          operand (the part between the ? and the colon) is the
  1037.          result. If the value of the first operand is zero, the
  1038.          value of the result is the value of the third operand
  1039.          (the part after the :).
  1040.  
  1041. Parentheses can be used to group operands in an expression. In the absence
  1042. of parentheses, binary operators are grouped according to the same
  1043. precedence given in the C language.
  1044.  
  1045. Grouping is from left to right for operators of equal precedence, except
  1046. for the ternary operator (? :), which is right to left.
  1047.  
  1048. Macros can be invoked within an expression, and the special macro $d() is
  1049. recognized. After all macros have been expanded, the expression must have
  1050. proper syntax. Any words in the expanded expression are treated as errors.
  1051.  
  1052. The error directive (!error) causes MAKE to stop and print a fatal
  1053. diagnostic containing the text after !error. It takes the format
  1054.  
  1055.    !error [any_text]
  1056.  
  1057. This directive is designed to be included in conditional directives to
  1058. allow a user-defined abort condition. 
  1059.  
  1060. The undefine directive (!undef) causes any definition for the named macro
  1061. to be forgotten. If the macro is currently undefined, this directive has no
  1062. effect. 
  1063.  
  1064.  Using MAKE
  1065. ============
  1066.  
  1067. You now know a lot about how to write makefiles; now's the time to learn
  1068. how to use them with MAKE. The simplest way to use MAKE is to type the
  1069. command
  1070.  
  1071.    MAKE
  1072.  
  1073. at the MS-DOS prompt. MAKE then looks for MAKEFILE; if it can't find it, it
  1074. looks for MAKEFILE.MAK; if it can't find that, it halts with an error
  1075. message.
  1076.  
  1077. You can specify a file with the -f option:
  1078.  
  1079.    MAKE -fstars.mak
  1080.  
  1081. The general syntax for MAKE is
  1082.  
  1083.    make option option ... target target ...
  1084.  
  1085. where option is a MAKE option (discussed later) and target is the name of a
  1086. target file to be handled by explicit rules.
  1087.  
  1088. If the command line does not include any target names, MAKE uses the first
  1089. target file mentioned in an explicit rule. If one or more targets are
  1090. mentioned on the command line, they will be built as necessary.
  1091.  
  1092. Here are some more examples of MAKE command lines:
  1093.  
  1094.    make -n -fstars.mak
  1095.    make -s
  1096.    make -Iinclude -DTURBO=c:\tp5\project
  1097.  
  1098.  
  1099.  The BUILTINS.MAK File
  1100. -----------------------
  1101.  
  1102. As you become familiar with MAKE, you will find that there are macros and
  1103. rules (usually implicit ones) that you use again and again. You've got
  1104. three ways of handling them. First, you can put them in every makefile you
  1105. create. Second, you can put them all in one file and use the !include
  1106. directive in each makefile you create. Third, you can put them all in a
  1107. file named BUILTINS.MAK.
  1108.  
  1109. Each time you run MAKE, it looks for a file named BUILTINS.MAK; if it finds
  1110. the file, MAKE reads it in before handling MAKEFILE (or whichever makefile
  1111. you want it to process).
  1112.  
  1113. The BUILTINS.MAK file is intended for any rules (usually implicit rules) or
  1114. macros that will be commonly used in files anywhere on your computer.
  1115.  
  1116. There is no requirement that any BUILTINS.MAK file exist. If MAKE finds a
  1117. BUILTINS.MAK file, it interprets that file first. If MAKE cannot find a
  1118. BUILTINS.MAK file, it proceeds directly to interpreting MAKEFILE (or
  1119. whatever makefile you specify).
  1120.  
  1121.  
  1122.  How MAKE Searches for Files
  1123. -----------------------------
  1124.  
  1125. MAKE will search for BUILTINS.MAK in the current directory or in the exec
  1126. directory if your computer is running under DOS 3.x. You should place this
  1127. file in the same directory as the MAKE.EXE file.
  1128.  
  1129. MAKE always searches for the makefile in the current directory only. This
  1130. file contains the rules for the particular executable program file being
  1131. built. The two files have identical syntax rules.
  1132.  
  1133. MAKE also searches for any !include files in the current directory. If you
  1134. use the -I (Include) option, it will also search in the specified
  1135. directory.
  1136.  
  1137.  
  1138.  MAKE Command-Line Options
  1139. ---------------------------
  1140.  
  1141.    -Didentifier   Defines the named identifier to the string consisting of
  1142.                   the single character 1.
  1143.  
  1144.    -Diden=string  Defines the named identifier iden to the string after
  1145.                   the equal sign. The string cannot contain any spaces or
  1146.                   tabs.
  1147.  
  1148.    -Idirectory    MAKE will search for include files in the indicated
  1149.                   directory (as well as in the current directory).
  1150.  
  1151.    -Uidentifier   Undefines any previous definitions of the named
  1152.                   identifier.
  1153.  
  1154.    -s             Normally, MAKE prints each command as it is about to be
  1155.                   executed. With the -s option, no commands are printed
  1156.                   before execution.
  1157.  
  1158.    -n             Causes MAKE to print the commands, but not actually
  1159.                   perform them. This is useful for debugging a makefile.
  1160.  
  1161.    -ffilename     Uses filename as the MAKE file. If filename does not
  1162.                   exist and no extension is given, tries filename.MAK.
  1163.  
  1164.    -? or -h       Prints help message.
  1165.  
  1166.  
  1167.  MAKE Error Messages
  1168. ---------------------
  1169.  
  1170.  Fatal Errors
  1171.  
  1172. Don't know how to make XXXXXXXX
  1173.    This message is issued when MAKE encounters a nonexistent file name in
  1174.    the build sequence, and no rule exists that would allow the file name to
  1175.    be built.
  1176.  
  1177. Error directive: XXXX
  1178.    This message is issued when MAKE processes an #error directive in the
  1179.    source file. The text of the directive is displayed in the message.
  1180.  
  1181. Incorrect command line argument: XXX
  1182.    This error occurs if MAKE is executed with incorrect command-line
  1183.    arguments.
  1184.  
  1185. Not enough memory
  1186.    This error occurs when the total working storage has been exhausted. You
  1187.    should try this on a machine with more memory. If you already have 640K
  1188.    in your machine, you may have to simplify the source file.
  1189.  
  1190. Unable to execute command
  1191.    This message is issued after attempting to execute a command. This could
  1192.    be a result of the command file not being found, or because it was
  1193.    misspelled. A less likely possibility is that the command exists but is
  1194.    somehow corrupted.
  1195.  
  1196. Unable to open makefile
  1197.    This message is issued when the current directory does not contain a
  1198.    file named MAKEFILE.
  1199.  
  1200.  
  1201.  Errors
  1202.  
  1203. Bad file name format in include statement
  1204.    Include file names must be surrounded by quotes or angle brackets. The
  1205.    file name was missing the opening quote or angle bracket.
  1206.  
  1207. Bad undef statement syntax
  1208.    An !undef statement must contain a single identifier and nothing else as
  1209.    the body of the statement.
  1210.  
  1211. Character constant too long
  1212.    Character constants can be only one or two characters long.
  1213.  
  1214. Command arguments too long
  1215.    The arguments to a command executed by MAKE were more than 127
  1216.    characters--a limit imposed by DOS.
  1217.  
  1218. Command syntax error
  1219.    This message occurs if
  1220.  
  1221.       o the first rule line of the makefile contained any leading
  1222.         whitespace.
  1223.  
  1224.       o an implicit rule did not consist of .ext.ext:.
  1225.  
  1226.       o an explicit rule did not contain a name before the : character.
  1227.  
  1228.       o a macro definition did not contain a name before the = character.
  1229.  
  1230. Division by zero
  1231.    A divide or remainder in an !if statement has a zero divisor.
  1232.  
  1233. Expression syntax error in !if statement
  1234.    The expression in an !if statement is badly formed--it contains a
  1235.    mismatched parenthesis, an extra or missing operator, or a missing or
  1236.    extra constant.
  1237.  
  1238. File name too long
  1239.    The file name given in an !include directive was too long for MAKE to
  1240.    process. File path names in MS-DOS must be no more than 78 characters
  1241.    long.
  1242.  
  1243. Illegal character in constant expression X
  1244.    MAKE encountered some character not allowed in a constant expression. If
  1245.    the character is a letter, this indicates a (probably) misspelled
  1246.    identifier.
  1247.  
  1248. Illegal octal digit
  1249.    An octal constant was found containing a digit of 8 or 9.
  1250.  
  1251. Macro expansion too long
  1252.    A macro cannot expand to more than 4096 characters. This error often
  1253.    occurs if a macro recursively expands itself. A macro cannot legally
  1254.    expand to itself.
  1255.  
  1256. Misplaced elif statement
  1257.    An !elif directive was encountered without any matching !if directive.
  1258.  
  1259. Misplaced else statement
  1260.    An !else directive was encountered without any matching !if directive.
  1261.  
  1262. Misplaced endif statement
  1263.    An !endif directive was encountered without any matching !if directive.
  1264.  
  1265. No file name ending
  1266.    The file name in an include statement was missing the correct closing
  1267.    quote or angle bracket.
  1268.  
  1269. Redefinition of target XXXXXXXX
  1270.    The named file occurs on the left-hand side of more than one explicit
  1271.    rule.
  1272.  
  1273. Unable to open include file XXXXXXXXX.XXX
  1274.    The named file could not be found. This could also be caused if an
  1275.    include file included itself. Check whether the named file exists.
  1276.  
  1277. Unexpected end of file in conditional started on line #
  1278.    The source file ended before MAKE encountered an !endif. The !endif was
  1279.    either missing or misspelled.
  1280.  
  1281. Unknown preprocessor statement
  1282.    A ! character was encountered at the beginning of a line, and the
  1283.    statement name following was not error, undef, if, elif, include, else,
  1284.    or endif.
  1285.  
  1286.  
  1287. *  *  *  *  *
  1288.